(function () {

	var xml2js = require("xml2js"),
		parserOptions = {
			explicitArray: false,
			explicitRoot: true
		};

	function getOperators(rawData, model) {
		var operators = {};
		var keys = Object.keys(model);
		for (var i in keys) {
			var key = keys[i];
			if (!model.hasOwnProperty(key) || key === "__type") continue;
			var operator = rawData["op_" + key];
			if (operator) operators[key] = operator;
		}
		return operators;
	}

	function Deserializer(typeMappings) {
		this.typeMappings = typeMappings;
		this.deserialize = function (xml) {
			var dataRequest = {};
			var parser = new xml2js.Parser(parserOptions);
			parser.parseString(xml, function (err, result) {
				if (err) throw "Format wejściowego dokumentu XML jest niepoprawny";
				var type = Object.keys(result)[0];
				if (!typeMappings[type]) throw "Nie zdefiniowano konstruktora dla obiektów typu '" + type + "'";
				var rawData = result[type];

				dataRequest.model = new typeMappings[type](rawData);
				dataRequest.type = dataRequest.model.__type;
				dataRequest.operators = getOperators(rawData, dataRequest.model);
				dataRequest.method = rawData.metoda;
			});
			
			return dataRequest;
		}
	}

	module.exports = Deserializer;

})();